/**
 * 文件处理
 */

import path from "path";
import fs from "fs";
import crypto from "crypto";

class File {
  /**
   * @function writeFileSync 保存文件
   * @param {String} src
   * @param {String|Buffer} data
   */
  writeFileSync(src, data) {
    let dirname = path.dirname(src);
    if (!fs.existsSync(dirname)) {
      this.mkdirsSync(dirname);
    }
    fs.writeFileSync(src, data, {
      encoding: "utf-8",
    });
  }

  /**
   * @function readFileSync 读取文件
   * @param {String} src
   * @param {Object} options
   * @return {String|Buffer}
   */
  readFileSync(src, options = {}) {
    let dirname = path.dirname(src);
    if (!fs.existsSync(dirname)) {
      this.mkdirsSync(dirname);
    }
    return fs.readFileSync(src, options);
  }

  /**
   * @function readFileList 读取文件列表
   * @param {String} dirpath 要读取的文件路径
   */
  readFileList(dirpath) {
    let filesList = [];
    let files = fs.readdirSync(dirpath);
    files.forEach((name) => {
      const filepath = dirpath + path.sep + name;
      let stat = fs.statSync(filepath);
      if (stat.isDirectory()) {
        filesList = filesList.concat(this.readFileList(filepath));
      } else {
        let obj = {};
        obj.path = filepath;
        obj.name = name;
        filesList.push(obj);
      }
    });
    return filesList;
  }

  /**
   * @function appendFileSync 更改文件内容
   * @param {String} src 需要追加的文件路径
   * @param {String|Object} data 需要追加数据
   * @param {String} options
   */
  appendFileSync(src, data, options) {
    let dirname = path.dirname(src);
    if (!fs.existsSync(dirname)) {
      this.mkdirsSync(src);
    }
    data = typeof data === "string" ? data : JSON.stringify(data);
    try {
      fs.appendFileSync(src, data + "\n", options);
      console.log('The "data to append" was appended to file!');
    } catch (err) {
      /* Handle the error */
    }
  }

  /**
   * @function mkdirsSync 递归创建目录 同步方法
   * @param {String} dirname 目录名称
   */
  mkdirsSync(dirname) {
    if (fs.existsSync(dirname)) {
      return true;
    } else if (this.mkdirsSync(path.dirname(dirname))) {
      fs.mkdirSync(dirname);
      return true;
    }
  }

  /**
   * @function existsDir 判断文件或目录是否存在
   * @param pathname
   * @returns {boolean}
   */
  existsSync(pathname) {
    return fs.existsSync(pathname);
  }

  /**
   * @function createHash 获取内容hash
   * @param content 内容
   * @param length  hash长度
   */
  createHash(content, length) {
    return crypto
      .createHash("md5")
      .update(content)
      .digest("hex")
      .substring(0, length);
  }

  /**
   * @function getRelativePath 获取目录相对路径
   * @param {String} from 文件全路径
   * @param {String} to 需要引入的文件全路径
   * @return {String}
   */
  getRelativePath(from, to) {
    let relative = path.relative(path.dirname(from), to);
    return relative.split(path.sep).join("/");
  }

  /**
   * @function deleteFolder 删除目录
   * @param dirpath
   */
  rmdirSync(dirpath) {
    const _this = this;
    if (fs.existsSync(dirpath)) {
      const files = fs.readdirSync(dirpath);
      files.forEach((filename) => {
        let filepath = dirpath + path.sep + filename;
        if (fs.statSync(filepath).isDirectory()) {
          _this.rmdirSync(filepath);
        } else {
          fs.unlinkSync(filepath);
        }
      });
      fs.rmdirSync(dirpath);
    }
  }
}

export default new File();
